package com.example.pluginmanager.interceptor;

import cn.hutool.core.util.StrUtil;
import com.common.eunm.ExceptionCode;
import com.common.exception.TokenExpireException;
import com.example.pluginmanager.entity.User;
import com.example.pluginmanager.service.UserService;
import com.example.pluginmanager.util.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class ValidateJwtTokenInterceptor implements HandlerInterceptor {

    public static final ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

    /*
    * 后面把@value都抽成配置类
    * */
    @Value("${loginOut.prefix}")
    private String loginOutPrefix;

    @Value("${jwt.requestHeaderName}")
    private String requestHeaderName;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("=============================ValidateJwtTokenInterceptor=============================");
        log.info("============= requestUri:{}",request.getRequestURI());
        String access_token = request.getHeader(requestHeaderName);
        if (StrUtil.isEmpty(access_token)){
            throw new TokenExpireException(ExceptionCode.TOKEN_EXPIRE_EXEC.getMsg());
        }

        if (access_token.startsWith("Bearer ")){
            Boolean aBoolean = redisTemplate.hasKey(loginOutPrefix + access_token);
            if (Boolean.TRUE.equals(aBoolean)){
                throw new TokenExpireException(ExceptionCode.TOKEN_EXPIRE_EXEC.getMsg());
            }

            String token = access_token.substring("Bearer ".length());
            String userNameFromToken = jwtTokenUtil.getUserNameFromToken(token);
            log.info("=============================username:{}",userNameFromToken);
            User userByUsername = userService.getUserByUsername(userNameFromToken);
            if (userByUsername != null){
                if (jwtTokenUtil.validateToken(token,userByUsername)){
                    userThreadLocal.set(userByUsername);
                    return true;
                }
            }else {
                throw new TokenExpireException(ExceptionCode.TOKEN_EXPIRE_EXEC.getMsg());
            }
        }else {
            throw new TokenExpireException(ExceptionCode.TOKEN_EXPIRE_EXEC.getMsg());
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        ValidateJwtTokenInterceptor.userThreadLocal.remove();
    }
}
